﻿Imports System.ComponentModel
Imports Q2Q.Audio.Helpers
Namespace Audio.Players
	Public MustInherit Class PlayerBase
		Inherits DependencyObject
		Implements INotifyPropertyChanged


#Region "Property Change Notifications"
		Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
		Friend Sub RaisePropertyChanged(PropertyName As String)
			RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(PropertyName))
		End Sub
#End Region


		''' <summary>
		''' The File this Player will Playback when Started
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property File As String
			Get
				Return GetValue(FileProperty)
			End Get

			Set(ByVal value As String)
				SetValue(FileProperty, value)
			End Set
		End Property
		''' <summary>
		''' Represents the File Property
		''' </summary>
		''' <remarks></remarks>
		Public Shared ReadOnly FileProperty As DependencyProperty = _
							   DependencyProperty.Register("File", _
							   GetType(String), GetType(PlayerBase), _
							   New PropertyMetadata(Nothing))

		''' <summary>
		''' Gets a readonly value of whether or not the audio is playing.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		MustOverride ReadOnly Property IsPlaying As Boolean

		''' <summary>
		''' Gets a readonly value of whether or not the audio is paused.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		MustOverride ReadOnly Property IsPaused As Boolean


		''' <summary>
		''' Gets a readonly value of whether or not the audio is stopped.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		MustOverride ReadOnly Property IsStopped As Boolean


		Private FadeInDurationStatic As String = "FadeInDuration"
		Private FadeInDurationProperty As Double = 0
		''' <summary>
		''' The length of time (in seconds) for the audio to fade in over when the audio is played.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property FadeInDuration As Double
			Get
				Return FadeInDurationProperty
			End Get
			Set(value As Double)
				FadeInDurationProperty = value
				RaisePropertyChanged(FadeInDurationStatic)
			End Set
		End Property

		Private FadeOutDurationStatic As String = "FadeOutDuration"
		Private FadeOutDurationProperty As Double = 0
		''' <summary>
		''' The length of time (in seconds) for the audio to fade out over when the audio is stopped.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property FadeOutDuration As Double
			Get
				Return FadeOutDurationProperty
			End Get
			Set(value As Double)
				FadeOutDurationProperty = value
				RaisePropertyChanged(FadeOutDurationStatic)
			End Set
		End Property

		''' <summary>
		''' Sets the current volume of the cue.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		MustOverride Property Volume As Single

		''' <summary>
		''' The desired final playback volume of the player, after any fade in. 0 - 1.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		Public Property TargetVolume As Single
			Get
				Return TargetVolumeProperty
			End Get
			Set(value As Single)
				TargetVolumeProperty = value
				RaisePropertyChanged("TargetVolume")
				Volume = value
			End Set
		End Property

		''' <summary>
		''' Represents the TargetVolume Property.
		''' </summary>
		''' <remarks></remarks>

		Private TargetVolumeProperty As Single = 0.5

		''' <summary>
		''' Gets or Sets the pan value for the player. -1 is hard left. +1 is hard right.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		MustOverride Property Pan As Single

		''' <summary>
		''' When true the cue will automatically loop until manually stopped.
		''' </summary>
		''' <value></value>
		''' <returns></returns>
		''' <remarks></remarks>
		MustOverride Property EnableLoop As Boolean

		''' <summary>
		''' When set to true will prevent the audio file from continuing to loop past the point it is 'stopped'.
		''' </summary>
		''' <remarks></remarks>
		Private PreventLoop As Boolean = False



		Private StartTimeProperty As New TimeSpan(0)
		Public Property StartTime As TimeSpan
			Get
				Return StartTimeProperty
			End Get
			Set(value As TimeSpan)
				If StartTimeProperty <> value Then
					StartTimeProperty = value
					RaisePropertyChanged("StartTime")
				End If
			End Set
		End Property
		


#Region "Functions"

		''' <summary>
		''' Starts the file playing or resumes the player from pause.
		''' </summary>
		''' <remarks></remarks>
		MustOverride Sub Play(Optional UseFade As Boolean = True)

		''' <summary>
		''' Stops the audio player.
		''' </summary>
		''' <remarks></remarks>
		MustOverride Sub [Stop](Optional UseFade As Boolean = True)

		''' <summary>
		''' Mutes the audio volume.
		''' </summary>
		''' <remarks></remarks>
		MustOverride Sub Mute()

		''' <summary>
		''' Pauses the audio playback.
		''' </summary>
		''' <remarks></remarks>
		MustOverride Sub Pause()

		''' <summary>
		''' Creates a new audio Player. Requires the name of the file to play.
		''' </summary>
		''' <param name="FileToPlay"></param>
		''' <remarks>This MUST be overloaded by inheriting classes, as the base implementation does NOTHING.</remarks>
		Public Sub New(FileToPlay As String)
		End Sub

		''' <summary>
		''' Creates a new player, however doesn't process anything. The player won't work, since no file name was passed into the constructor.
		''' </summary>
		''' <remarks></remarks>
		Public Sub New()
		End Sub


		''' <summary>
		''' Must be overridden by the inheriting class, provided it needs to.
		''' </summary>
		''' <remarks></remarks>
		Public Overridable Sub Dispose()
			'Does nothing - must be implemented by the inheriting classes.
		End Sub
#End Region
	End Class

	Public Enum PlayerTypes
		Wave
		Wasapi
		Asio
	End Enum
End Namespace